 package com.zhangqiang.git.opc.opclink.config;

 import com.zhangqiang.git.opc.opclink.model.Result;
 import org.jinterop.dcom.common.JIException;
 import org.jinterop.dcom.core.JIVariant;
 import org.openscada.opc.lib.common.ConnectionInformation;
 import org.openscada.opc.lib.da.Group;
 import org.openscada.opc.lib.da.Item;
 import org.openscada.opc.lib.da.Server;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;

 import javax.annotation.PreDestroy;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Executors;

 /**
  * OPC 连接配置
  */

@Configuration
public class OpcConfig {

    @Value(value = "${opc.host}")
    private String host;
    @Value(value = "${opc.userName}")
    private String userName;
    @Value(value = "${opc.password}")
    private String password;
    @Value(value = "${opc.clsid}")
    private String clsid;
    @Value(value = "${opc.progId}")
    private String progId;

    private static Server OPC_SERVER = null;

     /**
      * 服务退出时关闭OPC连接
      */
     @PreDestroy
     public void destory(){
         if(OPC_SERVER!=null)OPC_SERVER.disconnect();
     }

     /**
      * OPC客户端初始化连接
      *
      */
    public void initOpcClient(){
        closeConnectServer();
        // 连接信息
        final ConnectionInformation ci = new ConnectionInformation();
        ci.setHost(host);                   // 电脑IP
        ci.setDomain("");                   // 域，为空就行
        ci.setUser(userName);               // 电脑上自己建好的用户名
        ci.setPassword(password);           // 用户名的密码

        // 使用KEPServer的配置 二选一即可
        if(progId!=null && !"false".equals(progId)){
            ci.setProgId(progId);   // 服务标识
        }else{
            ci.setClsid(clsid);     // KEPServer的注册表ID，可以在“组件服务”里看到
        }

        // 启动服务
        OPC_SERVER = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        try {
            OPC_SERVER.connect();
        } catch (Exception e) {
            closeConnectServer();
        }
    }

    /**
     * 获取opc 客户端
     * @return
     */
    private Server getServer(){
        if(OPC_SERVER == null){
            initOpcClient();
        }
        return OPC_SERVER;
    }

    /**
     * 单标签读取数据
     * @param itemId
     * @return
     */
    public Result readItemValue(String itemId){
        Server server = getServer();
        if(server == null)return Result.fail(server);
        try {
            Group group = server.addGroup();
            Item item = group.addItem(itemId);
            JIVariant jiVariant = item.read(false).getValue();
            return Result.success(jiVariant.getObject());
        }catch (Exception e){
            closeConnectServer();
            return  Result.err(e);
        }
    }

    /**
     * 多标签读取数据
     * @param itemIds
     * @return
     */
    public Result readItemsValues(String... itemIds){
        Server server = getServer();
        if(server == null)return Result.fail(server);
        try {
            Group group = server.addGroup();
            Map<String,Object> item_values = new HashMap<String, Object>();
            Map<String, Item> itemMap = group.addItems(itemIds);
            itemMap.forEach((key, item) -> {
                try {
                    JIVariant jiVariant = item.read(false).getValue();
                    item_values.put(key,jiVariant.getObject());
                } catch (JIException e) {
                    e.printStackTrace();
                }
            });
            return Result.success(item_values);
        }catch (Exception e){
            closeConnectServer();
            return  Result.fail(e);
        }

    }

    /**
     * 单标签写入值
     * @param itemId
     * @param value
     * @return
     */
    public Result writeItemValue(String itemId,String value){
        Server server = getServer();
        if(server == null)return Result.fail(server);
        try {
            Group group = server.addGroup();
            Item item = group.addItem(itemId);
            item.write( new JIVariant(value));
            return Result.success("成功");
        }catch (Exception e){
            closeConnectServer();
            return Result.fail(e);
        }
    }

    //	关闭连接
    private void closeConnectServer() {
        //关闭客户端
        if (null != OPC_SERVER) {
            OPC_SERVER.disconnect();
        } else {
//            ("opc server is null");
        }
        OPC_SERVER = null;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getClsid() {
        return clsid;
    }

    public void setClsid(String clsid) {
        this.clsid = clsid;
    }

    public String getProgId() {
        return progId;
    }

    public void setProgId(String progId) {
        this.progId = progId;
    }
}
